using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Xfinity.Engine;
using System.Diagnostics;
using System.Text;

namespace Xfinity.Console
{
    /// <summary>
    /// A console.
    /// </summary>
    public static class StandardConsole
    {
        static StandardConsole()
        {
            baseStream = new MemoryStream();
            writer = new StreamWriter(baseStream);
            reader = new StreamReader(baseStream);

        }
        private static MemoryStream baseStream;
        private static StreamWriter writer;
        private static StreamReader reader;

        [DebuggerStepThrough]
        public static void Fail(string message)
        {
            Fail(message, null);
        }
        private static bool redirectInputToConsole;

        /// <summary>
        /// 
        /// </summary>
        public static bool RedirectInputToConsole
        {
            [DebuggerStepThrough]
            get { return redirectInputToConsole; }
            [DebuggerStepThrough]
            set { redirectInputToConsole = value; }
        }

        private static StringBuilder inputLine = new StringBuilder();

        /// <summary>
        /// 
        /// </summary>
        public static StringBuilder InputLine
        {
            [DebuggerStepThrough]
            get { return inputLine; }
            [DebuggerStepThrough]
            set { inputLine = value; }
        }


        private static bool consoleShowing = false;

        /// <summary>
        /// 
        /// </summary>
        public static bool ConsoleShowing
        {
            [DebuggerStepThrough]
            get { return consoleShowing; }
            [DebuggerStepThrough]
            set { consoleShowing = value; }
        }
        [DebuggerStepThrough]
        public static void Read()
        {
            try
            {
                string command = inputLine.ToString();
                CommandParser.ProcessCommand(command);
            }
            catch (CommandFailedException e)
            {
                WriteLine(e.Commands[0] + ": Command not recognised.");
            }
        }

        [DebuggerStepThrough]
        public static void Fail(string message, string detailMessage)
        {
            WriteLine(message.ToUpper(),true);
            if (detailMessage != null)
            {
                WriteLine("",true);
                WriteLine(detailMessage,true);
            }
        }

        private static List<bool> isFailMessage = new List<bool>(1000);

        /// <summary>
        /// 
        /// </summary>
        public static List<bool> IsFailMessage
        {
            [DebuggerStepThrough]
            get { return isFailMessage; }
        }

        private static List<string> transcript = new List<string>(1000);

        /// <summary>
        /// Gets or sets the transcript.
        /// </summary>
        /// <value>The transcript.</value>
        public static List<string> Transcript
        {
            [DebuggerStepThrough]
            get { return transcript; }
        }
        [DebuggerStepThrough]
        public static void Write(string message)
        {
            writer.Write(message);
            transcript.Add(message);
        }

        [DebuggerStepThrough]
        public static void WriteLine(string message)
        {
            WriteLine(message, false);
        }
        [DebuggerStepThrough]
        private static void WriteLine(string message, bool isFail)
        {
            writer.WriteLine(message);
            transcript.Add(message + Environment.NewLine);
            isFailMessage.Add(isFail);
        }
        private static Console defaultConsole;

        /// <summary>
        /// The default console.
        /// </summary>
        public static Console DefaultConsole
        {
            [DebuggerStepThrough]
            get { return defaultConsole; }
            [DebuggerStepThrough]
            set { defaultConsole = value; }
        }
    }
}